#!/usr/bin/env python

__author__ = 'Tom MacWright (macwright [ -a- ] gmail.com)'
__copyright__ = 'Copyright 2010, Development Seed'
__version__ = '2.0'
__license__ = 'BSD'

import sqlite3, urllib2, os, sys, base64, zipfile, logging
from flask import Flask, render_template, request, redirect, url_for, send_file, jsonify, json, send_file
from werkzeug import Response, secure_filename
#import DLZ libraries
from db import *
import pacp
from logger import create_logger

logger = create_logger('my logger')
logger.setLevel(logging.INFO)

try:
    import json
except ImportError:
    import simplejson as json



DATA_DIR = 'data'

PACP_SRC = 'data/pacp.sqlite'
WINDSHIELD_SRC = 'data/windshield.sqlite'
PHOTO_PATH = r'F:\windshield_htdoc\windshield_photos'
FLV_PATH = r'H:\pacp_htdoc\flv'

def layer_entry(file):
    """ return a layer entry for /layers """
    
    result = MetaInfo().getMeta(os.path.join(DATA_DIR,file))
    result['path'] = base64.urlsafe_b64encode(os.path.join(DATA_DIR, file))
    result['file'] = file
    return result
	

def layer_valid(file):
    """ filter layers to prevent .DS_Store, etc. files from
    causing problems. """
    logger.info(os.path.join(DATA_DIR, file))
    #meta = MetaInfo().getMeta(os.path.join(DATA_DIR, file))
    if os.path.splitext(file)[1] in ['.sqlite']:
        try:
            meta = MetaInfo().getMeta(os.path.join(DATA_DIR, file))
            if meta:
                return True
        except:
            pass
            

def layers_list(folder):
    """ return a json object of layers ready for configuration """
    for root, dirs, files in os.walk(folder):
        for x in files:
            logger.info('%s: %s' % (x, str(layer_valid(x))))
        return map(layer_entry, [x for x in files if layer_valid(x)])


##
# WEB-EXPOSED FUNCTIONS
##

app = Flask(__name__)

@app.route('/', methods=['GET'])
def home():
    """ serve the home page """
    return redirect('/static/map.html')
    return render_template('start.html')


@app.route('/layers', methods=['GET'])
def layers():
    """ layers callback: returns information about map layers in MAPS_DIR """
    #try:
    return jsonify({'layers': layers_list(DATA_DIR)})
    #except Exception, e:
    #    return str(e)

#####################
#windshield
#####################
@app.route('/houses', methods=['GET', 'POST'])
def houses():
    """ serve the home page """
    limit = request.args.get('limit', 20)
    offset = request.args.get('start', 0)
    fld = request.args.get('fld', '')
    val = request.args.get('val', '')
    
    
    if fld and val:
        #a query
        sql = "select dlzpid, pid, address from parcel where %s like '%%%s%%' order by pid limit ?  offset ? " % (fld, val)
    else:
        sql = 'select dlzpid, pid, address from parcel order by pid limit ?  offset ?'
    
    conn = sqlite3.connect(WINDSHIELD_SRC)
    c = conn.cursor()
    results = []
    tct = 0
    for x in c.execute('select count() from parcel'):
            tct = x[0]
    for x in c.execute(sql, [limit, offset]):
        results.append(dict(zip(['dlzpid', 'pid', 'address'], x)))
    
    
    return jsonify({ "totalcount": tct,  "runs": results})

@app.route('/photos/<string:table>/<string:photo_type>/<string:photo_path>', methods=['GET', 'POST'])
def getphoto(table, photo_type, photo_path):
    drive_name = os.getcwd().split(':')[0]
    p = PHOTO_PATH.replace('F', drive_name)
   
    if table=='parcel':
        if photo_type=='thumb':
			f = file(os.path.join(r'%s\thumb\parcels' % p,  photo_path), 'rb')
        else:
			f = file(os.path.join(r'%s\photo\parcels' % p,  photo_path), 'rb')
	return Response(f, mimetype="video/x-flv", direct_passthrough=True)



@app.route('/houses/query', methods=['GET', 'POST'])
def housesquery():
    """ serve the home page """
    dlzpid = request.args.get('id')
    fields = 'dlzpid    pid    address    weather    maintenance    structure    property_type    property_type_comment    ds1    ds2    ds3    ds4    ds5    ds6    ds7    ds8    ds9    ds10    ds11    gutter    area_drain    yard_drain    sump_pump    roadside_ditch    curb_gutter    outlet1    outlet2    garage    garage_downspouts    garage_gutters    comment    logid    vacant    section_missing    outlet3'.split()
    sql = 'select %s from parcel where dlzpid=?' % ','.join(fields)

    conn = sqlite3.connect(WINDSHIELD_SRC)
    c = conn.cursor()
    r = {}
    
   
    for x in c.execute(sql, [int(dlzpid)]):
       r = dict(zip(fields, x))
    
    dss = []
    photos = []
    
    for i in range(1,10):
        v = '%s (%s).jpg' % (r['pid'], i)
        photos.append({'name': v, 'url': v})
    result = {'empty': 'No', 'photos': photos}
    outlets = []
    for fld in fields:
        if r[fld]:
                v = r[fld]
        else:
                v = 'None'
        if fld.startswith('ds'):
            dss.append({'n': fld, 'c': v})
        elif fld.startswith('outlet'):
            
            dss.append({'n': fld, 'c': v})
        else:
            result[fld] = v
    result['outlets'] = outlets
    result['ds'] = dss
    return jsonify({"details": [result]})


###############
#PACP 
###############
@app.route('/runs', methods=['GET', 'POST'])
def runs():
    """ serve the home page """
    limit = request.args.get('limit', 20)
    offset = request.args.get('start', 0)
    query = request.args.get('query', 'all')
    format = request.args.get('format', None)
    p = pacp.PACPLibrary(PACP_SRC)
    results = p.getRuns(query, limit, offset)
    tct = p.runCount()
    if format=='html':
        t = ''
        if results:
            
            return Response('<br>'.join(['<a href="/static/pacp/pacp.htm?%s" target="_blank">%s</a>' % (r['PIPETECHID'],r['PIPETECHID']) for r in results]))
        else:
            return Response('No Video Found')
    return jsonify({ "totalcount": tct,  "runs": results})

@app.route('/detail', methods=['GET'])
def details():
    """ serve the home page """
    runid = int(request.args.get('query', 1))
    p = pacp.PACPLibrary(PACP_SRC)
    results = p.getDetails(runid)
    return jsonify({ "totalcount": len(results),  "details": results})


@app.route('/flv/<string:name>', methods=['GET'])
def flv(name):
    drive_name = os.getcwd().split(':')[0]
    p = FLV_PATH.replace('F', drive_name)
    
    f = file(os.path.join(p, name), 'rb')
    
    return Response(f, mimetype="video/x-flv", direct_passthrough=True)

  

###########################
#gwc tiles
###########################

@app.route(
    '/gwc/<string:layername_64>/<string:z>/<string:x>/<string:y>.png', 
    methods=['GET'])
def gwc_tile(layername_64, z, x, y):
    """ serve a tile request """
    layername = "%s" % base64.urlsafe_b64decode(str(layername_64))
    
    return Response(TileDatabase().getTile(layername, x, y, z), mimetype="image/png")
@app.route(
    '/osm/<string:z>/<string:x>/<string:y>.png', 
    methods=['GET'])
def osm_tile(z, x, y):
    """ serve a tile request """
    return Response(TileDatabase().getTile('data/osm.sqlite', x, y, z), mimetype="image/png")

#########################
#vector query
########################    
@app.route(
    '/vector/<string:layername_64>/<string:hashlist>', 
    methods=['GET'])
def vector_query(layername_64, hashlist):
    """ serve a vector request """
    layername = "%s" % base64.urlsafe_b64decode(str(layername_64))
    ws = []
    for h in hashlist.split(','):
        ws.append("substr(geohash, 0, %s) = '%s'" % (len(h), h))
    sql = 'select geojson from feature where %s' % ' OR '.join(ws)
    
    #sql = 'select NODE, substr(geohash,0, 9), substr(geohash,0, 9) in (%s)  from %s where NODE="0015T0466"' % (','.join(["'%s'" % x for x in hashlist.split(',')]), layer)
    #sql = 'select * from storm_nodes'
    geojson = VectorDatabase().query(sql, layername)
    return jsonify(geojson)
    
##
# SERVER BOOTER
##

if __name__ == "__main__":
    """ since flask spawns a new process when run from the mac terminal,
    write a pid file to keep track of this process """
    if sys.platform == 'darwin':
        spid = open('server.pid', 'w')
        spid.write("%s\n" % str(os.getpid()))
        spid.close()
    #app.config['SERVER_NAME'] = 'localhost'
    app.debug = True
    app.run(host='0.0.0.0')
